﻿namespace JadeX.HtmlMarkupMinifier.Controllers
{
    using System.Linq;
    using System.Web.Mvc;

    using JadeX.HtmlMarkupMinifier.Models;
    using JadeX.HtmlMarkupMinifier.ViewModels;

    using Orchard;
    using Orchard.Caching;
    using Orchard.ContentManagement;
    using Orchard.Environment.Features;
    using Orchard.Localization;
    using Orchard.Security;
    using Orchard.UI.Admin;
    using Orchard.UI.Notify;

    [Admin]
    public class AdminController : Controller
    {
        private readonly ISignals signals;

        private readonly IFeatureManager featureManager;

        public AdminController(IOrchardServices services, ISignals signals, IFeatureManager featureManager)
        {
            this.Services = services;
            this.signals = signals;
            this.featureManager = featureManager;
        }

        public IOrchardServices Services { get; set; }

        public Localizer T { get; set; }

        public ActionResult Index()
        {
            if (!this.Services.Authorizer.Authorize(StandardPermissions.SiteOwner, this.T("Not allowed to manage Html Minification - Features")))
            {
                return new HttpUnauthorizedResult();
            }

            var settings = this.Services.WorkContext.CurrentSite.As<MinificationSettingsPart>();

            var model = new IndexViewModel
            {
                OutputCachingEnabled = this.featureManager.GetEnabledFeatures().FirstOrDefault(x => x.Id == "Orchard.OutputCache") != null,

                WhitespaceMinificationMode = settings.WhitespaceMinificationMode,
                RemoveHtmlComments = settings.RemoveHtmlComments,
                RemoveHtmlCommentsFromScriptsAndStyles = settings.RemoveHtmlCommentsFromScriptsAndStyles,
                RemoveCdataSectionsFromScriptsAndStyles = settings.RemoveCdataSectionsFromScriptsAndStyles,
                UseShortDoctype = settings.UseShortDoctype,
                UseMetaCharsetTag = settings.UseMetaCharsetTag,
                EmptyTagRenderMode = settings.EmptyTagRenderMode,
                RemoveOptionalEndTags = settings.RemoveOptionalEndTags,
                RemoveTagsWithoutContent = settings.RemoveTagsWithoutContent,
                CollapseBooleanAttributes = settings.CollapseBooleanAttributes,
                RemoveEmptyAttributes = settings.RemoveEmptyAttributes,
                AttributeQuotesRemovalMode = settings.AttributeQuotesRemovalMode,
                RemoveRedundantAttributes = settings.RemoveRedundantAttributes,
                RemoveJsTypeAttributes = settings.RemoveJsTypeAttributes,
                RemoveCssTypeAttributes = settings.RemoveCssTypeAttributes,
                RemoveHttpProtocolFromAttributes = settings.RemoveHttpProtocolFromAttributes,
                RemoveHttpsProtocolFromAttributes = settings.RemoveHttpsProtocolFromAttributes,
                RemoveJsProtocolFromAttributes = settings.RemoveJsProtocolFromAttributes,
                MinifyEmbeddedCssCode = settings.MinifyEmbeddedCssCode,
                MinifyInlineCssCode = settings.MinifyInlineCssCode,
                MinifyEmbeddedJsCode = settings.MinifyEmbeddedJsCode,
                MinifyInlineJsCode = settings.MinifyInlineJsCode
            };

            return this.View(model);
        }

        [HttpPost, ActionName("Index")]
        public ActionResult IndexPost()
        {
            if (!this.Services.Authorizer.Authorize(StandardPermissions.SiteOwner, this.T("Not allowed to manage Html Minification - Features")))
            {
                return new HttpUnauthorizedResult();
            }

            var model = new IndexViewModel();

            if (this.TryUpdateModel(model))
            {
                var settings = this.Services.WorkContext.CurrentSite.As<MinificationSettingsPart>();

                settings.WhitespaceMinificationMode = model.WhitespaceMinificationMode;
                settings.RemoveHtmlComments = model.RemoveHtmlComments;
                settings.RemoveHtmlCommentsFromScriptsAndStyles = model.RemoveHtmlCommentsFromScriptsAndStyles;
                settings.RemoveCdataSectionsFromScriptsAndStyles = model.RemoveCdataSectionsFromScriptsAndStyles;
                settings.UseShortDoctype = model.UseShortDoctype;
                settings.UseMetaCharsetTag = model.UseMetaCharsetTag;
                settings.EmptyTagRenderMode = model.EmptyTagRenderMode;
                settings.RemoveOptionalEndTags = model.RemoveOptionalEndTags;
                settings.RemoveTagsWithoutContent = model.RemoveTagsWithoutContent;
                settings.CollapseBooleanAttributes = model.CollapseBooleanAttributes;
                settings.RemoveEmptyAttributes = model.RemoveEmptyAttributes;
                settings.AttributeQuotesRemovalMode = model.AttributeQuotesRemovalMode;
                settings.RemoveRedundantAttributes = model.RemoveRedundantAttributes;
                settings.RemoveJsTypeAttributes = model.RemoveJsTypeAttributes;
                settings.RemoveCssTypeAttributes = model.RemoveCssTypeAttributes;
                settings.RemoveHttpProtocolFromAttributes = model.RemoveHttpProtocolFromAttributes;
                settings.RemoveHttpsProtocolFromAttributes = model.RemoveHttpsProtocolFromAttributes;
                settings.RemoveJsProtocolFromAttributes = model.RemoveJsProtocolFromAttributes;
                settings.MinifyEmbeddedCssCode = model.MinifyEmbeddedCssCode;
                settings.MinifyInlineCssCode = model.MinifyInlineCssCode;
                settings.MinifyEmbeddedJsCode = model.MinifyEmbeddedJsCode;
                settings.MinifyInlineJsCode = model.MinifyInlineJsCode;

                this.signals.Trigger(MinificationSettingsPart.CacheKey);

                this.Services.Notifier.Information(this.T("Feature settings saved successfully."));
            }
            else
            {
                this.Services.Notifier.Error(this.T("Could not save feature settings."));
            }

            return this.RedirectToAction("Index");
        }

        public ActionResult Exclusions()
        {
            if (!this.Services.Authorizer.Authorize(StandardPermissions.SiteOwner, this.T("Not allowed to manage Html Minification - Exclusions")))
            {
                return new HttpUnauthorizedResult();
            }

            var settings = this.Services.WorkContext.CurrentSite.As<MinificationSettingsPart>();

            var model = new IndexViewModel
            {
                ExcludeAdmin = settings.ExcludeAdmin,
                ExcludeAuthenticated = settings.ExcludeAuthenticated,
                HaltOnWarnings = settings.HaltOnWarnings,
                IgnoredUrls = settings.IgnoredUrls
            };

            return this.View(model);
        }

        [HttpPost, ActionName("Exclusions")]
        public ActionResult ExclusionsPost()
        {
            if (!this.Services.Authorizer.Authorize(StandardPermissions.SiteOwner, this.T("Not allowed to manage Html Minification - Exclusions")))
            {
                return new HttpUnauthorizedResult();
            }

            var model = new IndexViewModel();

            if (this.TryUpdateModel(model))
            {
                var settings = this.Services.WorkContext.CurrentSite.As<MinificationSettingsPart>();

                settings.ExcludeAdmin = model.ExcludeAdmin;
                settings.ExcludeAuthenticated = model.ExcludeAuthenticated;
                settings.HaltOnWarnings = model.HaltOnWarnings;
                settings.IgnoredUrls = model.IgnoredUrls;
                
                this.signals.Trigger(MinificationSettingsPart.CacheKey);

                this.Services.Notifier.Information(this.T("Exclusion settings saved successfully."));
            }
            else
            {
                this.Services.Notifier.Error(this.T("Could not save exclusion settings."));
            }

            return this.RedirectToAction("Exclusions");
        }
    }
}